package com.winner.data.util;

import java.io.IOException;

import org.apache.http.Consts;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * HttpUtil工具类发送get/post请求
 *
 * @author wangxinle5
 * @since 2022/04/25
 */
@Slf4j
public class HttpUtil {

    // @PostConstruct注解好多人以为是Spring提供的。而是来自于java的标准库(javax.annotation.PostConstruct).它属于JSR-250(Java Specificaion Request 250)规范,
    // 该规范定义了一些常用的注解,用于支持Java类的声明性注解和声明周期管理.你可以在任何支持JSR-250规范的环境中使用它,而不仅限于Spring框架.

    // JSR303/JSR-349: JSR303是一项标准,只提供规范不提供实现，规定一些校验规范即校验注解，如@Null，@NotNull，@Pattern，
    // 位于javax.validation.constraints包下。JSR-349是其的升级版本，添加了一些新特性
    // https://blog.csdn.net/fsjwin/article/details/114448286
    // JSR是Java Specification Requests的缩写，意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR，以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。
    // 说人话就是你要提交一个java的规范，就要提出申请，比如你要顶一个@MyName的注解，代表一定的含义，可以提出申请，待批复后，其他各大开源厂商可能均会使用你的这个规范。
    private static final RequestConfig REQUEST_CONFIG = RequestConfig.custom()
            // 设置连接超时时间(单位毫秒)
            .setConnectTimeout(60000)
            // 链接建立成功后,数据包传输超时时间(单位毫秒)
            .setSocketTimeout(60000)
            // 从连接池获取连接的超时限制，不常用 (单位毫秒)
            .setConnectionRequestTimeout(30000).build();

    /**
     * post请求 结果返回null就是调用http请求失败了 String s = null; User user = JSON.parseObject(s, User.class); 也是不会空指针的, 不过最好是判断 !=
     * null, 再反序列化为对象
     *
     * @param url         post请求的url
     * @param requestBody 入参body里的json字符串
     * @return 结果
     */
    public static String post(String url, String requestBody) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // HttpClient 4.3 版本开始，连接管理是由连接管理器（Connection Manager）负责，不再需要手动释放连接, 不需要post.releaseConnection()
        HttpPost post = new HttpPost(url);

        post.setConfig(REQUEST_CONFIG);
        // 设置请求体
        StringEntity requestEntity = new StringEntity(requestBody, Consts.UTF_8);
        post.setEntity(requestEntity);
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(post);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                return EntityUtils.toString(response.getEntity(), Consts.UTF_8);
            }
        } catch (Exception e) {
            log.error("post request error, error message is {}", e.getMessage());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                log.error("response/httpClient close error");
            }
        }
        return null;
    }

    /**
     * get请求
     *
     * @param url get请求的url
     * @return 结果
     */
    public static String get(String url) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 设置请求体
        HttpGet get = new HttpGet(url);
        get.setConfig(REQUEST_CONFIG);
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(get);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                return EntityUtils.toString(response.getEntity(), Consts.UTF_8);
            }
        } catch (Exception e) {
            log.error("get request error, error message is {}", e.getMessage());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                log.error("response/httpClient close error");
            }
        }
        return null;
    }

    public static void main(String[] args) {
        String post = post("", "");
        System.out.println(post);
    }

}
